package commSql

import (
	"errors"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntity"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Json"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Reflect"
	"strconv"
)

type entitySQL struct {
}

func (e *entitySQL) getTableName(entityType string) (string, error) {
	// 获得表信息
	tablePtr := schema.schema[entityType]
	if tablePtr == nil {
		return "", errors.New("在schema中找不到定义：" + entityType)
	}
	table := tablePtr.(map[string]interface{})

	// 取出表名称和字段信息
	name := table[constTableName].(string)
	return name, nil
}

func (e *entitySQL) Select(entityType string) (string, error) {
	// 获得表信息
	tablePtr := schema.schema[entityType]
	if tablePtr == nil {
		return "", errors.New("在schema中找不到定义：" + entityType)
	}
	table := tablePtr.(map[string]interface{})

	// 取出表名称和字段信息
	name := table[constTableName].(string)
	tableFields := table[constTableField].(map[string]interface{})

	// 拼接成SQL语句
	sql := "SELECT"
	for k := range tableFields {
		sql += " " + k + ","
	}
	sql = sql[0 : len(sql)-1]
	sql += " FROM " + name
	return sql, nil
}

func (e *entitySQL) SelectWhere(entityType string, where string) (string, error) {
	sql, err := e.Select(entityType)
	if err != nil {
		return "", err
	}

	sql += " WHERE (" + where + ")"
	return sql, nil
}

func (e *entitySQL) SelectWhereId(entityType string, id int64) (string, error) {
	return e.SelectWhere(entityType, "ID = "+strconv.FormatInt(id, 10))
}

func (e *entitySQL) DeleteWhere(entityType string, where string) (string, error) {
	tableName, err := e.getTableName(entityType)
	if err != nil {
		return "", err
	}

	sql := "DELETE FROM " + tableName + " WHERE (" + where + ")"
	return sql, nil
}

func (e *entitySQL) DeleteWhereId(entityType string, id int64) (string, error) {
	return e.DeleteWhere(entityType, "ID = "+strconv.FormatInt(id, 10))
}

func (e *entitySQL) Insert(entity commEntity.IEntity) (string, []interface{}, error) {
	if entity == nil {
		return "", nil, errors.New("输入的entity不能为空")
	}

	entityType := entity.Type()

	tblName, err := Map.GetValue(schema.schema, entityType, constTableName)
	if err != nil {
		return "", nil, err
	}

	return e.InsertRecord(tblName.(string), entity)
}

func (e *entitySQL) InsertRecord(tblName string, entity commEntity.IEntity) (string, []interface{}, error) {
	if entity == nil {
		return "", nil, errors.New("输入的entity不能为空")
	}

	// 转成接口，准备调用接口函数
	entityType := entity.Type()
	po := entity.BuildToPo()

	// 取出表结构信息
	fptr, err := Map.GetValue(schema.schema, entityType, constTableField)
	if err != nil {
		return "", nil, err
	}
	fields := fptr.(map[string]interface{})

	values := make([]interface{}, 0)
	sql := "INSERT INTO "
	sql += "`" + tblName + "` ("
	for _, v := range fields {
		field := v.(map[string]interface{})
		dataType := field[constDataType].(string)
		fieldName := field[constFieldName].(string)

		// 插入语句，不包含Id字段
		if fieldName == "Id" {
			continue
		}

		// 字段区
		sql += "`" + field[constColumnName].(string) + "`"
		sql += ","

		// 数值区
		if dataType == "string" {
			val, err := Reflect.GetField(po, fieldName)
			if err != nil {
				return "", nil, err
			}

			values = append(values, val.(string))
		} else if dataType == "int64" {
			val, err := Reflect.GetField(po, fieldName)
			if err != nil {
				return "", nil, err
			}

			values = append(values, strconv.FormatInt(val.(int64), 10))
		} else if dataType == "int" {
			val, err := Reflect.GetField(po, fieldName)
			if err != nil {
				return "", nil, err
			}

			values = append(values, strconv.Itoa(val.(int)))
		} else if dataType == "bool" {
			val, err := Reflect.GetField(po, fieldName)
			if err != nil {
				return "", nil, err
			}

			str := ""
			if true == val {
				str = "1"
			} else {
				str = "0"
			}

			values = append(values, str)
		} else if dataType == "map[string]interface {}" || dataType == "[]int64" || dataType == "[]map[string]interface {}" {
			val, err := Reflect.GetField(po, fieldName)
			if err != nil {
				return "", nil, err
			}
			jsn := Json.BuildJson(val)

			values = append(values, jsn)
		} else {
			panic("不支持的数据类型:" + dataType)
		}

	}
	sql = sql[0 : len(sql)-1]
	sql += ") VALUES ("

	valueStr := ""
	for i := 0; i < len(values); i++ {
		valueStr += "?,"
	}
	valueStr = valueStr[:len(valueStr)-1]

	sql += valueStr
	sql += ")"

	return sql, values, nil
}

func (e *entitySQL) UpdateWhereId(entity commEntity.IEntity) (string, []interface{}, error) {
	if entity == nil {
		return "", nil, errors.New("输入的entity不能为空")
	}

	entityType := entity.Type()

	tblName, err := Map.GetValue(schema.schema, entityType, constTableName)
	if err != nil {
		return "", nil, err
	}

	return e.UpdateRecordWhereId(tblName.(string), entity)
}

func (e *entitySQL) UpdateRecordWhereId(tableName string, entity commEntity.IEntity) (string, []interface{}, error) {
	if entity == nil {
		return "", nil, errors.New("输入的entity不能为空")
	}

	entityType := entity.Type()
	po := entity.BuildToPo()

	// 取出表结构信息
	fptr, err := Map.GetValue(schema.schema, entityType, constTableField)
	if err != nil {
		return "", nil, err
	}
	fields := fptr.(map[string]interface{})

	values := make([]interface{}, 0)
	sql := "UPDATE " + tableName + " SET "
	for _, v := range fields {
		field := v.(map[string]interface{})
		dataType := field[constDataType].(string)
		fieldName := field[constFieldName].(string)

		// 插入语句，不包含Id字段
		if fieldName == "Id" {
			continue
		}

		// 字段区
		sql += "`" + field[constColumnName].(string) + "`= ?"
		sql += ","

		// 数值区
		if dataType == "string" {
			val, err := Reflect.GetField(po, fieldName)
			if err != nil {
				return "", nil, err
			}

			values = append(values, val.(string))
		} else if dataType == "int64" {
			val, err := Reflect.GetField(po, fieldName)
			if err != nil {
				return "", nil, err
			}

			values = append(values, strconv.FormatInt(val.(int64), 10))
		} else if dataType == "int" {
			val, err := Reflect.GetField(po, fieldName)
			if err != nil {
				return "", nil, err
			}

			values = append(values, strconv.Itoa(val.(int)))
		} else if dataType == "bool" {
			val, err := Reflect.GetField(po, fieldName)
			if err != nil {
				return "", nil, err
			}

			str := ""
			if true == val {
				str = "1"
			} else {
				str = "0"
			}

			values = append(values, str)
		} else if dataType == "map[string]interface {}" || dataType == "[]int64" || dataType == "[]map[string]interface {}" {
			val, err := Reflect.GetField(po, fieldName)
			if err != nil {
				return "", nil, err
			}
			jsn := Json.BuildJson(val)

			values = append(values, jsn)
		} else {
			panic("不支持的数据类型:" + dataType)
		}

	}
	sql = sql[0 : len(sql)-1]

	sql += " WHERE ID = " + strconv.FormatInt(entity.GetBaseEntity().Id, 10)

	return sql, values, nil
}
